package com.lin.filegraph.utils.storage;

import java.util.ArrayList;
import java.util.List;

import com.lin.filegraph.utils.compdg.ComponentEdge;
import com.lin.filegraph.utils.compdg.ComponentGraph;
import com.lin.filegraph.utils.compdg.ComponentNode;
import com.lin.filegraph.utils.componentRule.ComponentDepend;
import com.lin.filegraph.utils.filedg.FileGraphNode;
import com.lin.filegraph.utils.model.ComponentModule;
import com.lin.filegraph.utils.model.Module;
import com.lin.filegraph.utils.moduledg.ModuleNode;
import com.lin.filegraph.utils.name.ComRename;
import com.lin.filegraph.utils.name.DirSimilarity;
import com.lin.filegraph.utils.threshold.Threshold;
import org.bson.Document;

/**
 * @description:
 * @author: linhuaixu
 * @time: 2023/5/18 15:41
 */

public class ModuleStorage {


    public static int search(String name, String centernode, List<ComponentNode> comlist) {
        for (ComponentNode node : comlist) {
            if (node.getStrComponentName().equals(name) && node.getCenternode().equals(centernode)) {
                return comlist.indexOf(node);
            }
        }
        return -1;
    }

    public static int search(String name, int locOfCom, List<ModuleNode> comlist) {
        for (ModuleNode node : comlist) {
            if (node.getModuleName().equals(name) && node.getLocOfCom() == locOfCom) {
                return comlist.indexOf(node);
            }
        }
        return -1;
    }

    public static String getSimpleName(String s) {
        String[] str = s.split("/");
        return str[str.length - 1];
    }

    public static String searchModuleName(String fileName, List<ModuleNode> comlist) {
        for (ModuleNode moduleNode : comlist) {
            List<FileGraphNode> fileList = moduleNode.getAllFiles();
            for (FileGraphNode file : fileList) {
                if (file.getFileName().equals(fileName)) {
                    return moduleNode.getModuleName();
                }
            }
        }
        return "";
    }

    public static void cacheModuleGraph(ComponentGraph graph, List<Module> comList, List<ComponentModule> fileList, List<ComponentDepend> comdList, int level) {
        for (ComponentNode cn : graph.getAllComponents()) {
            //
            cacheModule(comList, cn, graph, level, fileList);
        }
        for (ComponentEdge ce : graph.getAllComponentEdges()) {
            String c1 = ce.getPreComponent().getID() + "";
            String c2 = ce.getPostComponent().getID() + "";
            boolean isHave = false;
            for (ComponentDepend comd : comdList) {
                if (comd.getComponent_D().equals(c1) && comd.getComponentFrom().equals(c2)) {
                    isHave = true;
                    break;
                }
            }
            if (!isHave)
                comdList.add(new ComponentDepend(c1, c2, ce.getDependence(), ce.getCouplingTypes()));
        }
    }

    //如果目录数多于1或者聚类层数>4或没开始聚类，设置聚类次数
    public static void cacheModule(List<Module> comList, ComponentNode cn, ComponentGraph graph, int level, List<ComponentModule> fileList) {
        if (cn.getAllDirs().size() > 1 || level == 4 || level == 0) {
            cn.setLevel(level);

            String name = Threshold.TEST;
            //如果未分离特征，根据目录重命名组件名称
            if (!cn.isFeature())
                name = ComRename.getComNameByDir(cn);// 父模块
            cn.setID(graph.addLastNum());// 编号
            cn.reComName(name);// 重命名
            String simple = DirSimilarity.getSimpleName(name);
            // 命名加入规模文件
            if (level < 4) {
                simple = cn.getCenternode();
            }
            if (simple.equals("") || simple == null)
                simple = Threshold.UNKNOWN;
            comList.add(new Module(cn.getID(), simple, cn.getStrComponentName(), -1, level, cn.getAllFiles().size(), cn.getLocOfCom()));// 父模块
            // 发生变化

            if (cn.getAllDirs() != null || !cn.getAllDirs().isEmpty()) {
                for (String str : cn.getAllDirs()) {// 子模块
                    if (str == null)
                        throw new IllegalArgumentException("模块存储异常！");
                    try {
                        int spacer = str.indexOf(Threshold.SPACER);
                        int id = Integer.parseInt(str.substring(spacer + 1));
                        for (Module m : comList) {
                            if (m.getID() == id && m.getBelongModule() == -1) {
                                m.setBelongModule(cn.getID());
                            }
                        }
                    } catch (Exception e) {
                        System.out.println("%%%%%" + cn.getAllDirs().size());
                    }
                }
            }

            if (level < 3) {// 最后一层不处理
                cn.getAllDirs().clear();
                cn.addDir(cn.getStrComponentName());
                cn.setCenternode(cn.getCenternode());
                cn.setPreNum(cn.getLocOfCom());
            }
            // 存储文件从属关系
            if (cn.getAllFiles() != null) {
                for (String str : cn.getAllFiles()) {
                    if (str == null)
                        str = "";
                    fileList.add(new ComponentModule(cn.getID() + "", str, cn.getLocOfCom()));
                }
            }
        }
    }

    public static void storeModuleFile(ComponentGraph graph, boolean isClear, long proj, long ver) {
        List<ComponentModule> comList = new ArrayList<>();
        for (ComponentNode cn : graph.getAllComponents()) {
            String comInt = cn.getStrComponentName();
            if (cn.getAllFiles() != null) {
                for (String str : cn.getAllFiles()) {
                    if (str == null)
                        str = "";
                    comList.add(new ComponentModule(cn.getID() + "", str, cn.getLocOfCom()));
                }
            }
        }
        /*InsertDB.insertModuleFile(db, comList, proj, ver);*/
    }

    public static int searchf(String name, String absolutePath, List<FileGraphNode> ListOfFiles) {
        for (FileGraphNode node : ListOfFiles) {
            if (node.getFileName().equals(name) && node.getAbsolutePath().equals(absolutePath)) {
                return ListOfFiles.indexOf(node);
            }
        }
        return -1;
    }

    public static String changeFileName(String s) {
        String[] str = s.split("/");
        return str[str.length - 1];
    }

    public static boolean iscontains(List<Document> list, Document node) {
        for (Document fnode : list) {
            if (fnode.get("name").equals(node.get("name"))) {
                return true;
            }
        }
        return false;
    }
}

